package com.jeesite.modules.ocr.utils;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.img.ImgUtil;
import cn.hutool.core.lang.Assert;
import com.benjaminwan.ocrlibrary.Point;
import com.benjaminwan.ocrlibrary.TextBlock;
import lombok.extern.slf4j.Slf4j;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.List;

import javax.imageio.ImageIO;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.io.resource.ResourceUtil;
import com.benjaminwan.ocrlibrary.OcrResult;

import io.github.mymonstercat.Model;
import io.github.mymonstercat.ocr.InferenceEngine;
import io.github.mymonstercat.ocr.config.HardwareConfig;
import io.github.mymonstercat.ocr.config.ParamConfig;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;

/**
 * OCRImageUtils 公关类
 * @author 姚海陆,长春叭哥
 * @version 2024-07-28
 */
@Slf4j
public class OCRImageUtils extends ImgUtil {
	
	/**
	 * 绘制图片
	 * <p>
	 * 根据传入的坐标点绘制矩形框，并在矩形框底下添加文字
	 * </p>
	 *
	 * @param imageFile 图片文件
	 * @param blockList 文本块列表
	 * @return {@link OutputStream }
	 * @author song_jx
	 */
	public static ByteArrayOutputStream drawImg(File imageFile, List<TextBlock> blockList) {
		
		System.out.println("图片绘制:"+blockList.size());
		ByteArrayOutputStream os = null;
		try (InputStream is = new FileInputStream(imageFile)) {
			os = drawImg(is, blockList);
		} catch (Exception e) {
			log.error("图片绘制异常", e);
		}
		return os;
	}
	/**
	 * 绘制图片
	 * <p>
	 * 根据传入的坐标点绘制矩形框，并在矩形框底下添加文字
	 * </p>
	 *
	 * @param stream    数据流
	 * @param blockList 文本块列表
	 * @return {@link OutputStream }
	 * @author song_jx
	 */
	public static ByteArrayOutputStream drawImg(InputStream stream, List<TextBlock> blockList) {
		// 读取输入流中的图片
		BufferedImage image = read(stream);
		// 开启画笔绘制
		Graphics2D g2d = image.createGraphics();
		int no = 1;
		for (final TextBlock textBlock : blockList) {
				final List<Point> boxPoint = textBlock.getBoxPoint();
				final String text = "(" + no + ")" + textBlock.getText();
				no = no + 1;
				// 1. 算出矩形框
				final Rectangle box = calcRectangle(boxPoint);
				final int x = box.x;
				final int y = box.y;
				final int width = box.width;
				final int height = box.height;
				// 2. 绘制矩形框
				g2d.setColor(new Color((int) (Math.random() * 255), (int) (Math.random() * 255),
						(int) (Math.random() * 255)));
				g2d.drawRect(x, y, width, height);
				// 3. 在矩形框的左下角添加文字
				g2d.setColor(Color.black);

				if (width > height) {
					// 选择一个合适的字体大小
					int fontSize = getFontSizeToFit(g2d, text, width, height);
					// 设置字体
					Font font = new Font("Microsoft YaHei", Font.PLAIN, fontSize - 4);
					g2d.setFont(font);
				} else {
					// 选择一个合适的字体大小
					int fontSize = getFontSizeToFit(g2d, text, width, height);
					// 设置字体
					Font font = new Font("Microsoft YaHei", Font.PLAIN, fontSize + 6);
					g2d.setFont(font);
				}
				// 计算文本的位置，使其居中显示
				FontMetrics metrics = g2d.getFontMetrics();
				g2d.drawString(text, (width - metrics.stringWidth(text)) / 2 + box.x,
						(height + metrics.getAscent()) / 2 + box.y);

			

		}
		g2d.dispose();
		ByteArrayOutputStream os = new ByteArrayOutputStream();
		write(image, IMAGE_TYPE_PNG, os);
		return os;
	}

	/**
	 * 计算矩形框
	 *
	 * <p>
	 * 根据传入的4个坐标点，得出矩形框的左上角及长宽
	 * </p>
	 *
	 * @param pointList 点列表
	 * @return {@link Rectangle }
	 * @author song_jx
	 */
	private static Rectangle calcRectangle(List<Point> pointList) {
		Assert.isFalse(CollUtil.isEmpty(pointList) || pointList.size() != 4, "需要4个点来构成矩形");
		int minX = Integer.MAX_VALUE;
		int minY = Integer.MAX_VALUE;
		int maxX = Integer.MIN_VALUE;
		int maxY = Integer.MIN_VALUE;
		// 找到最小和最大的 x、y 坐标
		for (Point point : pointList) {
			final int x = point.getX();
			final int y = point.getY();
			if (x < minX) {
				minX = x;
			}
			if (y < minY) {
				minY = y;
			}
			if (x > maxX) {
				maxX = x;
			}
			if (y > maxY) {
				maxY = y;
			}
		}
		// 矩形的左上角坐标即是最小x、y
		final int width = maxX - minX;
		final int height = maxY - minY;
		return new Rectangle(minX, minY, width, height);
	}

	/**
	 * 根据矩形的宽度和高度计算一个适合的字体大小。
	 *
	 * @param g2d   Graphics2D 对象用于获取字体度量信息
	 * @param text  需要绘制的文本
	 * @param rectW 矩形的宽度
	 * @param rectH 矩形的高度
	 * @return 合适的字体大小
	 */
	private static int getFontSizeToFit(Graphics2D g2d, String text, int rectW, int rectH) {
		int minSize = 1;
		int maxSize = rectH; // 最大字体大小不应超过矩形的高度
		int size = maxSize / 2; // 初始字体大小设为高度的一半

		while (minSize < maxSize - 1) {
			Font font = new Font("Microsoft YaHei", Font.PLAIN, size);
			g2d.setFont(font);

			FontMetrics metrics = g2d.getFontMetrics();
			int stringWidth = metrics.stringWidth(text);
			int ascent = metrics.getAscent();

			if (stringWidth <= rectW && ascent <= rectH) {
				minSize = size;
			} else {
				maxSize = size;
			}

			size = (minSize + maxSize) / 2;
		}

		return size;
	}

}
